package com.thd.framework.mail.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.thd.framework.mail.dto.MailAuthenticator;
import com.thd.framework.mail.dto.MailDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * 该类可以直接通过new的方式进行创建
 * 传入三个参数
 *
 * mailUser:邮箱  例如：xxxxxxx@qq.com
 * mailPwd:密码   例如：12345678
 * mailHost:文件服务  例如：smtpinternal.qq.com
 *
 *
 */
public class MailServiceImpl implements MailService<MailDto>{
    private Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);

    private String filePath="temp";


    private  String mailUsr = "devil13th@163.com";
    private  String mailPwd = "ABRXRHCFHJZMYCKJ";
    private  String mailHost = "smtp.163.com";
    private String mailHostPort = "25";


    public MailServiceImpl(String mailUsr, String mailPwd, String mailHost,String mailHostPort) {
        this.mailUsr = mailUsr;
        this.mailHost = mailHost;
        this.mailPwd = mailPwd;
        this.mailHostPort = mailHostPort;
    }

    @Override
    public String sendMessage(MailDto mailDto) throws Exception {

        logger.info("====== send mail start ======= ");

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(mailDto);
        logger.info("params:"+json);



        Properties props = new Properties();
        // 发送服务器需要身份验证
        props.setProperty("mail.smtp.auth", "true");
        // 设置邮件服务器主机名
//        props.setProperty("mail.host", mailHost);
        props.setProperty("mail.smtp.host", mailHost);

        // 设置服务端口
        props.put("mail.smtp.port", this.mailHostPort);
        // 发送邮件协议名称
        props.setProperty("mail.transport.protocol", "smtp");

        MailAuthenticator authenticator =new MailAuthenticator(mailUsr,mailPwd);

        // 设置环境信息
        Session session = Session.getInstance(props,authenticator);
        MimeMessage message = new MimeMessage(session);
        String flag = "OK";
        // 设置发信人
        try {
            message.setFrom(new InternetAddress(mailUsr));
            logger.info("开始设置收件人");
            // 设置收件人
            int num = mailDto.getMailAddress().size();
            InternetAddress[] addresses = new InternetAddress[num];
            for (int i = 0; i < num; i++) {
                addresses[i] = new InternetAddress(mailDto.getMailAddress().get(i));
            }
            message.setRecipients(RecipientType.TO, addresses);
            // 设置主题
            message.setSubject(mailDto.getSubject());
            // 设置邮件内容
            //sms.setContent(sender.getMessage(), "text/html;charset=utf-8");
            //设置附件
            Multipart mp = new MimeMultipart();
            MimeBodyPart mbp = new MimeBodyPart();
            mbp.setContent(mailDto.getMessage(), "text/html;charset=utf-8");
            Map<String, byte[]> attachMap=mailDto.getAttachFiles();
            if(attachMap!=null){
                Iterator<Map.Entry<String, byte[]>> it =  attachMap.entrySet().iterator();
                mp.addBodyPart(mbp);
                while(it.hasNext()){
                    Map.Entry<String, byte[]> entry = it.next();
                    mbp=new MimeBodyPart();
                    String filename=entry.getKey(); //选择出每一个附件名
                    String path=filePath+"/"+filename;
                    save(entry.getValue(),path);
                    FileDataSource fds=new FileDataSource(path); //得到数据源
                    mbp.setDataHandler(new DataHandler(fds)); //得到附件本身并至入BodyPart
                    mbp.setFileName(MimeUtility.encodeWord(fds.getName()));  //得到文件名同样至入BodyPart
                    mp.addBodyPart(mbp);

                }
            }else{
                mp.addBodyPart(mbp);
            }

            message.setContent(mp);
            logger.info("begin send mail ...");
            Transport.send(message);

        } catch (MessagingException e) {
            e.printStackTrace();
            logger.error("发送邮件抛异常:"+e.getMessage());
            flag = e.getMessage();
        } catch (IOException e) {
            logger.error(e.getMessage());
            flag = e.getMessage();
        }

        return flag;
    }

    private void save(byte[] bytes,String filePath) throws IOException {
        File outFile =new File(filePath);
        if (!outFile.exists()) {
            if(outFile.getParent()!=null && !new File(outFile.getParent()).exists()){
                new File(outFile.getParent()).mkdirs();
            }
            boolean res = outFile.createNewFile();
            if(res){
                FileOutputStream outStream = new FileOutputStream(outFile);
                try {
                    outStream.write(bytes);
                }finally {
                    outStream.close();
                }
            }
        }
    }
}
